import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../data/models/board_element.dart';

class BoardWidget extends StatelessWidget {
  final GlobalKey boardKey;
  final double aspectRatio;
  final RxList<BoardElement> elements;
  final Size canvasSize;
  final Function(BoardElement) onElementSelected;
  final Function(String, Offset) onElementPositionChanged;
  final bool editable;
  final List<String>? textContents;

  const BoardWidget({
    super.key,
    required this.boardKey,
    required this.aspectRatio,
    required this.elements,
    required this.canvasSize,
    required this.onElementSelected,
    required this.onElementPositionChanged,
    this.editable = true,
    this.textContents,
  });

  /// 获取当前所有元素，如果传入了textContents则返回更新文本后的元素
  List<BoardElement> getCurrentElements() {
    print("textContents: ${textContents}");
    if (textContents == null) {
      return elements.toList();
    }

    // 创建一个新的列表来存储更新后的元素
    List<BoardElement> updatedElements = elements.toList();
    var textElements =
        updatedElements.where((e) => e is TextBoardElement).toList();

    var textIndex = 0;

    for (var i = 0; i < textElements.length; i++) {
      var textElement = textElements[i] as TextBoardElement;
      // 保存原始尺寸
      final oldWidth = textElement.size.value.width;
      final oldHeight = textElement.size.value.height;
      print("textElement: $textElement");
      print("textElement.textAlign.value: ${textElement.isLocked.value}");
      // 更新文本
      if (!textElement.isLocked.value && textIndex < textContents!.length) {
        textElement.text.value = textContents![textIndex];
        textElement.textController.text = textContents![textIndex];
        textIndex++;
      }
      textElement.updateTextSize();

      // 计算新的位置，根据对齐方式调整
      final newWidth = textElement.size.value.width;
      final newHeight = textElement.size.value.height;
      double offsetX;
      print("textElement.textAlign.value: ${textElement.textAlign.value}");
      // 根据文本对齐方式计算水平偏移
      switch (textElement.textAlign.value) {
        case TextAlign.left:
          offsetX = 0; // 左对齐时保持左边界不变
          break;
        case TextAlign.right:
          offsetX = oldWidth - newWidth; // 右对齐时保持右边界不变
          break;
        case TextAlign.center:
        default:
          offsetX = (oldWidth - newWidth) / 2; // 居中对齐时保持中心点不变
          break;
      }

      // 垂直方向保持居中对齐
      final offsetY = (oldHeight - newHeight) / 2;

      textElement.position.value = Offset(
        textElement.position.value.dx + offsetX,
        textElement.position.value.dy + offsetY
      );
    }

    return updatedElements;
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final displayElements = editable ? elements : getCurrentElements();
      print("displayElements: $displayElements");
      return RepaintBoundary(
        key: boardKey,
        child: Container(
          width: Get.width,
          child: AspectRatio(
            aspectRatio: aspectRatio,
            child: Stack(
              fit: StackFit.expand,
              children: [
                // 首先渲染背景元素
                ...displayElements
                    .where((element) => element is BackgroundBoardElement)
                    .map(
                      (element) => Positioned(
                        left: element.position.value.dx,
                        top: element.position.value.dy,
                        right: 0,
                        bottom: 0,
                        child: GestureDetector(
                          onTap: editable
                              ? () => onElementSelected(element)
                              : null,
                          child: element.buildWidget(),
                        ),
                      ),
                    ),
                // 然后渲染其他元素
                ...displayElements
                    .where((element) => element is! BackgroundBoardElement)
                    .map(
                      (element) => Positioned(
                        left: element.position.value.dx,
                        top: element.position.value.dy,
                        width: element is TextBoardElement
                            ? null
                            : element.size.value.width,
                        height: element is TextBoardElement
                            ? null
                            : element.size.value.height,
                        child: editable
                            ? Draggable(
                                feedback: element.buildWidget(),
                                childWhenDragging: const SizedBox.shrink(),
                                child: GestureDetector(
                                  onTap: () => onElementSelected(element),
                                  child: element.buildWidget(),
                                ),
                                onDragEnd: (details) {
                                  final RenderBox renderBox = boardKey
                                      .currentContext!
                                      .findRenderObject() as RenderBox;
                                  final Offset localPosition =
                                      renderBox.globalToLocal(details.offset);

                                  final elementSize = element.size.value;

                                  // 校正位置，确保在画布范围内
                                  double newX = localPosition.dx;
                                  double newY = localPosition.dy;

                                  // 校正X轴
                                  if (newX < 0) {
                                    newX = 0;
                                  } else if (newX >
                                      canvasSize.width - elementSize.width) {
                                    newX = canvasSize.width - elementSize.width;
                                  }

                                  // 校正Y轴
                                  if (newY < 0) {
                                    newY = 0;
                                  } else if (newY >
                                      canvasSize.height - elementSize.height) {
                                    newY =
                                        canvasSize.height - elementSize.height;
                                  }

                                  onElementPositionChanged(
                                    element.id,
                                    Offset(newX, newY),
                                  );
                                },
                              )
                            : element.buildWidget(),
                      ),
                    ),
              ],
            ),
          ),
        ),
      );
    });
  }
}
